package io.github.wanggit.antrpc.commons.bean;

import io.github.wanggit.antrpc.commons.codec.compress.CompressUtil;
import io.github.wanggit.antrpc.commons.codec.cryption.ICodec;
import io.github.wanggit.antrpc.commons.constants.ConstantValues;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class RpcProtocolBuilder {

    private RpcProtocolBuilder() {
        throw new IllegalStateException();
    }

    public static void writeRpcProtocol(ByteBuf out, RpcProtocol msg) {
        out.writeInt(msg.getCmdId());
        out.writeByte(msg.getType());
        out.writeByte(msg.getCodec());
        out.writeByte(msg.getZip());
        out.writeByte(msg.getSerializer());
        // 8个字节的预留空间
        out.writeBytes(new byte[8]);
        out.writeInt(msg.getData().length);
        out.writeBytes(msg.getData());
    }

    public static void unzipAndDecodec(RpcProtocol rpcProtocol, ICodec codec) {
        byte[] data = rpcProtocol.getData();
        if (rpcProtocol.getZip() == ConstantValues.COMPRESSED) {
            if (log.isInfoEnabled()) {
                log.info(
                        "cmdId = "
                                + rpcProtocol.getCmdId()
                                + ". The received packet has been compressed and will be uncompressed before being used.");
            }
            data = CompressUtil.uncompress(data);
        }
        if (rpcProtocol.getCodec() == ConstantValues.CODECED) {
            data = codec.decrypt(data);
        }
        rpcProtocol.setData(data);
    }

    public static RpcProtocol build(ByteBuf byteBuf) {
        if (null == byteBuf) {
            return null;
        }
        if (byteBuf.readableBytes() <= ConstantValues.DECODER_HEADER_SIZE) {
            return null;
        }
        byteBuf.markReaderIndex();
        int cmdId = byteBuf.readInt();
        byte type = byteBuf.readByte();
        byte wasCodec = byteBuf.readByte();
        byte zip = byteBuf.readByte();
        byte serialzer = byteBuf.readByte();
        // 因为header还冗余8个字节，所以再读8个字节
        ByteBuf placeholder = byteBuf.readBytes(8);
        placeholder.release();
        // 读body长度
        int len = byteBuf.readInt();
        if (byteBuf.readableBytes() < len) {
            byteBuf.resetReaderIndex();
            return null;
        }
        byte[] data = new byte[len];
        byteBuf.readBytes(data);
        RpcProtocol rpcProtocol = new RpcProtocol();
        rpcProtocol.setCmdId(cmdId);
        rpcProtocol.setZip(zip);
        rpcProtocol.setCodec(wasCodec);
        rpcProtocol.setType(type);
        rpcProtocol.setSerializer(serialzer);
        rpcProtocol.setData(data);
        return rpcProtocol;
    }
}
